﻿using System;
using System.Collections.Generic;
using System.Text;

using System.Net;
using System.Net.Sockets;
namespace Net
{
    public class TCPIP : INetProcess
    {

        string status = "";
        Socket clintSocket = null;

        bool connected = false;

        public bool Connected
        {
            get { return connected; }
        }
        string IPOrHostName;
        int port;
        public TCPIP()
        {

        }

        public TCPIP(string IPOrHostName, int port)
        {
            this.IPOrHostName = IPOrHostName;
            this.port = port;
            clintSocket = ConnectSocket(IPOrHostName, port);

        }

        #region INetProcess Members
        public int ReadTimeout
        {
            get
            {
                return clintSocket.ReceiveTimeout;
            }
            set
            {
                clintSocket.ReceiveTimeout = value;
            }
        }
        private static Socket ConnectSocket(string server, int port)
        {
            Socket s = null;
            IPHostEntry hostEntry = null;

            // Get host related information.
            hostEntry = Dns.GetHostEntry(server);

            // Loop through the AddressList to obtain the supported AddressFamily. This is to avoid
            // an exception that occurs when the host IP Address is not compatible with the address family
            // (typical in the IPv6 case).
            foreach (IPAddress address in hostEntry.AddressList)
            {
                IPEndPoint ipe = new IPEndPoint(address, port);
                Socket tempSocket =
                    new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                tempSocket.Connect(ipe);

                if (tempSocket.Connected)
                {
                    s = tempSocket;
                    break;
                }
                else
                {
                    continue;
                }
            }
            return s;
        }


        public string ReadLine()
        {
            Byte[] sRecievedSubed = new Byte[128];
            string getStr = "";
            int bytes = 0;
            do
            {
                clintSocket.Receive(sRecievedSubed, sRecievedSubed.Length, 0);
            }
            while (bytes > 0);
            //int subIndex = 0;
            //Byte[] processedBytes;
            //if (sRecievedSubed.Length % 2 == 0)
            //{
            //    processedBytes = new byte[sRecievedSubed.Length / 2];
            //    for (int i = 0; i < processedBytes.Length; i++)
            //    {
            //        int high = (sRecievedSubed[i * 2] << 4) & 240;
            //        int low = ((sRecievedSubed[i * 2 + 1] << 4) & 240) >> 4;
            //        processedBytes[i] = (byte)(high | low);
            //        if (processedBytes[i] == 13)
            //        {
            //            subIndex = i;
            //            break;
            //        }

            //    }
            //}
            //else
            //{
            //    processedBytes = new byte[sRecievedSubed.Length / 2 + 1];
            //    for (int i = 0; i < processedBytes.Length - 1; i++)
            //    {
            //        int high = (sRecievedSubed[i * 2] << 4) & 240;
            //        int low = ((sRecievedSubed[i * 2 + 1] << 4) & 240) >> 4;
            //        processedBytes[i] = (byte)(high | low);
            //        if (processedBytes[i] == 13)
            //        {
            //            subIndex = i;
            //            break;
            //        }
            //    }
            //    int endhigh = (sRecievedSubed[processedBytes.Length - 1] << 4) & 240;
            //    processedBytes[processedBytes.Length - 1] = (byte)(endhigh | 0);
            //}
            //getStr = ASCIIEncoding.ASCII.GetString(processedBytes, 0, subIndex + 1);

            int subIndex = 0;
            for (int i = 0; i < sRecievedSubed.Length - 1; i++)
            {
                if (sRecievedSubed[i] == 13)
                 {
                     subIndex = i;
                     break;
                 }
            }
            return ASCIIEncoding.ASCII.GetString(sRecievedSubed, 0, subIndex + 1);

        }

        public int ReadByte()
        {
            throw new NotImplementedException();
        }

        public int Read(byte[] buffer, int offset, int count)
        {
            throw new NotImplementedException();
        }

        public void Write(string text)
        {
            clintSocket.Send(ASCIIEncoding.ASCII.GetBytes(text));
        }

        public void Write(byte[] buffer, int offset, int count)
        {
            clintSocket.Send(buffer);
        }

        public void WriteLine(string text)
        {
            throw new NotImplementedException();
        }

        public string CheckStatus()
        {
            throw new NotImplementedException();
        }

        public void DiscardInBuffer()
        {
            return;
        }

        public void DiscardOutBuffer()
        {
            return;
        }

        public event EventHandler Disposed;

        public void Dispose()
        {
            serverSock.Close();
            clintSocket.Close();
            serverSock = null;
            clintSocket = null;
        }

        #endregion

        private Socket serverSock;
        byte[] msgBuff = new byte[1024];
        /// <summary>
        /// 
        /// </summary>
        /// <param name="port">监听端口</param>
        /// <returns>返回监听状态</returns>
        public bool Start(int port)
        {
            try
            {
                Console.WriteLine("开始监听···");
                serverSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                serverSock.Bind(new IPEndPoint(IPAddress.Any, port));
                serverSock.Listen(10);
                serverSock.BeginAccept(new AsyncCallback(OnConnectRequest), serverSock);
                return true;
            }
            catch (Exception ex)
            {
                status = ex.Message;
                return false;
            }

        }
        public string getStatus()
        {
            return status;
        }

        public void OnConnectRequest(IAsyncResult ar)
        {
            try
            {
                Console.WriteLine("监听到一个新的连接···");
                Socket listenerSock = (Socket)ar.AsyncState;
                NewConnection(listenerSock.EndAccept(ar));
                listenerSock.BeginAccept(new AsyncCallback(OnConnectRequest), listenerSock);
            }
            catch (Exception ex)
            {
                status = ex.Message;
            }

        }
        private void NewConnection(Socket clientSock)
        {
            this.clintSocket = clientSock;
            status = "连接客户端:" + clintSocket.RemoteEndPoint.ToString();
            connected = clintSocket.Connected;
        }


    }
}
